﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BVCommon.Entities;
using System.ComponentModel;
using System.Collections.ObjectModel;
using BVClient.CustomerServiceReference;

namespace BVClient.Managers
{
    public class CustomerProvider
    {
        private IList<Customer> customers;
        private ObservableCollection<BVCustomer> bvCustomers = new ObservableCollection<BVCustomer>();
        private bool isLoaded = false;

        public ObservableCollection<BVCustomer> GetCustomers()
        {
            if (!isLoaded)
            {
                loadData();
            }
            return bvCustomers;
        }

        public CustomerProvider()
        { }

        private void loadData()
        {
            using (CustomerServiceClient client = new CustomerServiceClient())
            {
                customers = client.GetData().ToList();
            }
            foreach (Customer item in customers)
            {
                bvCustomers.Add(new BVCustomer(item));
            }
            isLoaded = true;
        }

        public void SaveData()
        {
            using (CustomerServiceClient client = new CustomerServiceClient())
            {
                IList<Customer> list = new List<Customer>();
                foreach (BVCustomer item in bvCustomers)
                {
                    list.Add(ConvertToDbObject(item));
                }
                client.SaveData(list.ToArray());
            }
            customers.Clear();
            bvCustomers.Clear();
            loadData();
        }

        private Customer ConvertToDbObject(BVCustomer sourceItem)
        {
            IEnumerable<Customer> dbCustomers = (from p in customers
                                               where p.id == sourceItem.Id
                                               select p);
            if (dbCustomers.Count() == 0)
            {
                return new Customer()
                {
                    name = sourceItem.Name,
                    props = sourceItem.Props,
                    create_date = sourceItem.Created
                };
            }
            else if (dbCustomers.Count() == 1)
            {
                dbCustomers.ElementAt(0).name = sourceItem.Name;
                dbCustomers.ElementAt(0).props = sourceItem.Props;
                dbCustomers.ElementAt(0).create_date= sourceItem.Created;

                return dbCustomers.ElementAt(0);
            }
            else
            {
                throw new ArgumentException("Two or more items have equal isentifier");
            }
        }
    }

    public class BVCustomer : IDataErrorInfo
    {
        //private readonly Regex nameEx = new Regex(@"^[A-Za-z ]+$");

        public Int32 Id
        { get; set; }

        public string Name
        { get; set; }

        public string Props
        { get; set; }

        public DateTime Created
        { get; set; }

        public BVCustomer() { }

        public BVCustomer(Customer item)
        {
            Id = item.id;
            UpdateItem(item);
        }

        public void UpdateItem(Customer customer)
        {
            Name = customer.name;
            Props = customer.props;
            Created = (customer.create_date ?? DateTime.Now);
        }

        #region IDataErrorInfo Members

        public string Error
        {
            get
            {
                StringBuilder error = new StringBuilder();
                // iterate over all of the properties
                // of this object - aggregating any validation errors
                PropertyDescriptorCollection props = TypeDescriptor.GetProperties(this);
                foreach (PropertyDescriptor prop in props)
                {
                    string propertyError = this[prop.Name];
                    if (propertyError != string.Empty)
                    {
                        error.Append((error.Length != 0 ? ", " : "") + propertyError);
                    }
                }

                if (Created.AddYears(1).CompareTo(new DateTime(DateTime.Now.Year+1, 1, 1)) > 0)
                {
                    error.Append((error.Length != 0 ? ", " : "") + "Created date must be early then 01/01/" + DateTime.Now.Year+1);
                }
                return error.ToString();
            }
        }

        public string this[string columnName]
        {
            get
            {
                // apply property level validation rules
                if (columnName.Equals("Name") && String.IsNullOrEmpty(Name))
                {
                    return "Name cannot be null or empty";
                }
                if (columnName.Equals("Props") && String.IsNullOrEmpty(Props))
                {
                    return "Props cannot be null or empty";
                }
                return String.Empty;
            }
        }

        #endregion
    }
}
